package com.aramco.fion.util
{
	import com.aramco.fion.model.FlexConstants;
	
	import mx.collections.ArrayCollection;
	import mx.controls.DateField;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumnGroup;
	import mx.controls.dataGridClasses.DataGridColumn;
	
	public class BSPReportDataModelOO
	{
		
		public var xmlData:XML;
		public var metaData:ArrayCollection = new ArrayCollection(); ;
		public var repotData:ArrayCollection = new ArrayCollection();; 
		public var hierarchyMeta:Array = new Array();
		public var paginationData:Object;
		
		public var dataGridColumns:Array;
		
		
		private var fieldsWithKey:Array = new Array();
		
		
		
		
		public function BSPReportDataModelOO(xml:XML)
		{
			xmlData = xml; 
			getMetaData2(xmlData.descendants('META'));
			getReportData(xmlData.descendants('OUTPUT'));
			getPaginationData(xmlData.descendants('PAGING_INFO'));
			getDatagridColumns(repotData, metaData);
		}
		
		public function parse(xml:XML)
		{
			/*xmlData = xml; 
			getMetaData2(xmlData.descendants('META'));
			getReportData(xmlData.descendants('OUTPUT'));
			getPaginationData(xmlData.descendants('PAGING_INFO'));
			getDatagridColumns(repotData, metaData);*/
		}
		
		private function getMetaData(xml:XMLList):void
		{
			var obj:Object ;
			for each ( var itemNode : Object in xml.descendants('ITEM'))
			{
				obj = new Object();
				obj.FIELDNAME = itemNode.FIELDNAME.toString();
				obj.OUTPUTLEN = itemNode.OUTPUTLEN.toString();
				obj.DATATYPE = itemNode.DATATYPE.toString();
				obj.SCRTEXT_L = itemNode.SCRTEXT_L.toString();
				obj.AXIS_TYPE = itemNode.AXIS_TYPE.toString();
				obj.TYPE = itemNode.TYPE.toString();
				obj.ELEM = itemNode.ELEM.toString();
				metaData.addItem(obj);
			}	
		}
		
		private function getPaginationData(xml:XMLList):void
		{
			paginationData = new Object();
			for each ( var itemNode : Object in xml)
			{
				
				paginationData.RECORD_NO = itemNode.RECORD_NO.toString();
				paginationData.TOTAL_REC = itemNode.TOTAL_REC.toString();
				paginationData.PAGE_NO = itemNode.PAGE_NO.toString();
			}
		}
		
		
		private function getMetaData2(xml:XMLList):void
		{
			var obj:Object ;
			var hierarchyMetaObject:Object;
			for each ( var itemNode : Object in xml.elements('ZBW_QUERY_OUTPUT_METADATA'))
			{
				obj = new Object();
				//obj.FIELDNAME = CommonActions.stripCharacteristicName(itemNode.FIELDNAME.toString());
				obj.FIELDNAME = itemNode.FIELDNAME.toString();
				
				obj.OUTPUTLEN = itemNode.OUTPUTLEN.toString();
				obj.DATATYPE = itemNode.DATATYPE.toString();
				if(itemNode.DATATYPE.toString() != "DATS" && itemNode.FIELDNAME.toString().indexOf("VALUE") == -1)
				{
					if(itemNode.TYPE.toString() == "CHAR" || itemNode.DISPLAY_STYLE.toString() == "1" && itemNode.TYPE.toString()!= "KF")
						obj.SCRTEXT_L = itemNode.SCRTEXT_L.toString() + " (Desc)";
					else if(itemNode.TYPE.toString() == "KEY" || itemNode.DISPLAY_STYLE.toString() == "2" && itemNode.TYPE.toString()!= "KF")
						obj.SCRTEXT_L = itemNode.SCRTEXT_L.toString() + " (Key)";
					else
						obj.SCRTEXT_L = itemNode.SCRTEXT_L.toString();
				}
					
				else
					obj.SCRTEXT_L = itemNode.SCRTEXT_L.toString();
				
				obj.AXIS_TYPE = itemNode.AXIS_TYPE.toString();
				obj.TYPE = itemNode.TYPE.toString();
				obj.ELEM = itemNode.ELEM.toString();
				obj.DISPLAY_STYLE = itemNode.DISPLAY_STYLE.toString();
				hierarchyMetaObject = generateHierarchyMeta(obj.FIELDNAME,obj.SCRTEXT_L,obj.AXIS_TYPE);
				
				if(itemNode.DISPLAY_STYLE.toString() != "6")
					metaData.addItem(obj);
				
				if(itemNode.descendants('ZBW_QUERY_OUTPUT_METADATA').length() > 0
					&& obj.AXIS_TYPE == 'COLUMN')
				{
					var array:Array = new Array();
					for each(var itemNode2 : Object in itemNode.descendants('ZBW_QUERY_OUTPUT_METADATA'))
					{
						var obj2:Object = new Object();
						obj2.AXIS_TYPE = itemNode2.AXIS_TYPE.toString();
						obj2.SCRTEXT_L = itemNode2.SCRTEXT_L.toString() ;
						array.push(obj2)	
					}
					
					var obj3:Object = new Object();
					obj3.FIELDNAME = itemNode.FIELDNAME.toString();
					obj3.SCRTEXT_L = itemNode.SCRTEXT_L.toString();
					obj3.HEADERS = array;
					hierarchyMetaObject = obj3;
					
					obj.HEADERS_INFO = array;
				}
					
				else if(itemNode.descendants('ZBW_QUERY_OUTPUT_METADATA').length() > 0
					&& obj.AXIS_TYPE != 'COLUMN')
				{
					for each(var itemNode2 : Object in itemNode.descendants('ZBW_QUERY_OUTPUT_METADATA'))
					{
						//Key column
						if(itemNode2.FIELDNAME.toString().search('_key') >= 0)
						{
							var obj4:Object = new Object();
							//obj4.FIELDNAME = CommonActions.stripCharacteristicName(itemNode2.FIELDNAME.toString());
							obj4.FIELDNAME = itemNode2.FIELDNAME.toString();
							obj4.OUTPUTLEN = itemNode2.OUTPUTLEN.toString();
							obj4.DATATYPE = itemNode2.DATATYPE.toString();
							
							obj4.AXIS_TYPE = itemNode2.AXIS_TYPE.toString();
							obj4.TYPE = itemNode2.TYPE.toString();
							obj4.ELEM = itemNode2.ELEM.toString();
							
							if(obj4.DATATYPE != "DATS" && obj4.FIELDNAME.indexOf("VALUE") == -1 && itemNode.TYPE.toString()!= "KF")
								obj4.SCRTEXT_L = itemNode2.SCRTEXT_L.toString() + " (Key)";
							else
								obj4.SCRTEXT_L = itemNode2.SCRTEXT_L.toString();
							obj4.DISPLAY_STYLE = itemNode2.DISPLAY_STYLE.toString();
							
							//Key and Text
							if(obj4.DISPLAY_STYLE == '0' || obj4.DISPLAY_STYLE == 'F')
							{
								var tmpVar:String = metaData.getItemAt(metaData.length -1).FIELDNAME;
								if(obj4.FIELDNAME.toString().search(tmpVar) >= 0)
								{
									var tmp:Object = metaData.removeItemAt(metaData.length-1);
									metaData.addItem(obj4);
									
									if(tmp.DATATYPE != "DATS" && tmp.FIELDNAME.indexOf("VALUE") == -1 && itemNode.TYPE.toString()!= "KF")
										tmp.SCRTEXT_L = tmp.SCRTEXT_L + " (Desc)";
									
									
									metaData.addItem(tmp);
									
								}
								else
								{
									metaData.addItem(obj4);
								}	
							}
								
								//Text and Key
							else if(obj4.DISPLAY_STYLE == '3')
							{
								metaData.addItem(obj4);
							}
								
								//Text
							else if (obj4.DISPLAY_STYLE == '1')
							{
								
							}
								
								//Key
							else if (obj4.DISPLAY_STYLE == '2')
							{
								metaData.removeItemAt(metaData.length-1);
								metaData.addItem(obj4);
							}
								
								
								//No Display
							else if (obj4.DISPLAY_STYLE == '6')
							{
								//	metaData.removeItemAt(metaData.length-1);
							}
						}
						
						//Handling Display Attributes
						if(itemNode2.@type == "ATR")
						{
							var obj4:Object = new Object();
						//	obj4.FIELDNAME = CommonActions.stripCharacteristicName(itemNode2.FIELDNAME.toString());
							obj4.FIELDNAME = itemNode2.FIELDNAME.toString();
							obj4.OUTPUTLEN = itemNode2.OUTPUTLEN.toString();
							obj4.DATATYPE = itemNode2.DATATYPE.toString();
							
							
							
							obj4.AXIS_TYPE = itemNode2.AXIS_TYPE.toString();
							obj4.TYPE = itemNode2.TYPE.toString();
							
							if(obj4.DATATYPE.toString() != "DATS" && obj4.FIELDNAME.toString().indexOf("VALUE00") == -1
								&&  itemNode2.DISPLAY_STYLE.toString()  == '2')
								obj4.SCRTEXT_L = itemNode2.SCRTEXT_L.toString() + " (Key)";
							else if(obj4.DATATYPE.toString() != "DATS" && obj4.FIELDNAME.toString().indexOf("VALUE00") == -1
								&&  itemNode2.DISPLAY_STYLE.toString()  == '1')
								obj4.SCRTEXT_L = itemNode2.SCRTEXT_L.toString() + " (Desc)";
							else
								obj4.SCRTEXT_L = itemNode2.SCRTEXT_L.toString();
							
							obj4.ELEM = itemNode2.ELEM.toString();
							obj4.DISPLAY_STYLE = itemNode2.DISPLAY_STYLE.toString();
							metaData.addItem(obj4);
						}
					}
				}
				
				hierarchyMeta.push(hierarchyMetaObject);
			}
			
			for(var i:int = 0 ;i < metaData.length; i++)
			{
				if(metaData[i].DISPLAY_STYLE == '6')
					metaData.removeItemAt(i);
			}
		}
		
		private function generateHierarchyMeta(fieldName:String,textHeader:String, axisType:String):Object
		{
			var obj:Object = new Object();
			obj.AXIS_TYPE = axisType;
			obj.FIELDNAME = fieldName;
			obj.SCRTEXT_L = textHeader;
			obj.HEADERS = null;
			return obj;
		}
		
		private function getReportData(xml:XMLList):void
		{
			var obj:Object;
			var x:int = 0;
			for each ( var itemNode : XML in xml.descendants('item'))
			{
				var tmp:XMLList = itemNode.children();
				obj = new Object();
				for(var i:int = 0; i < tmp.length(); i++)
				{
					var obj2:XML = tmp[i];
					if(obj2.toString() != "")
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	obj2.toString();
						obj[obj2.name().localName] =	obj2.toString();
					else
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	"#";
						obj[obj2.name().localName] =	"#";
				}
				repotData.addItem(obj);
			}
		}
		public static function getFormated(xml:XMLList):ArrayCollection
		{
			var obj:Object;
			var x:int = 0;
			var repotData:ArrayCollection = new ArrayCollection();
			for each ( var itemNode : XML in xml.descendants('item'))
			{
				var tmp:XMLList = itemNode.children();
				obj = new Object();
				for(var i:int = 0; i < tmp.length(); i++)
				{
					var obj2:XML = tmp[i];
					if(obj2.toString() != "")
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	obj2.toString();
						obj[obj2.name().localName] =	obj2.toString();
					else
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	"#";
						obj[obj2.name().localName] =	"#";
				}
				repotData.addItem(obj);
			}
			return repotData;
		}
		
		private function isKeyField(str:String):Boolean
		{
			for(var i:int = 0 ; i < fieldsWithKey.length; i++)
			{
				if(str == fieldsWithKey[i].KEY)
				{
					return true;
					break;
				}
			}
			return  false;
		}
		
		private function getKeyField(str:String):String
		{
			for(var i:int = 0 ; i < fieldsWithKey.length; i++)
			{
				if(str == fieldsWithKey[i].LABEL)
				{
					return fieldsWithKey[i].KEY;
					break;
				}
			}
			return  "";
		}
		
		public function getGridDataProvider():Object
		{
			return repotData;
		}
		
		public function getDatagridColumns(outputXMLReportData:ArrayCollection, signature:ArrayCollection):void
		{
		//	myView = event.data.view;
		//	myView.bar1.removeAllChildren();
		//	var signature:ArrayCollection = _CommonModel.outputXMLReportMetaData;
			var myColumns:Array = new Array();
			var searchFieldBarIndex=-1;
			if(signature!=null)
			{
				myColumns = new Array();
				for(var i:int = 0; i < signature.length; i++)
				{
					var adgcg:AdvancedDataGridColumnGroup;
					var dgColumn:AdvancedDataGridColumn;
					if((signature[i]).DISPLAY_STYLE != 6)
					{
						searchFieldBarIndex++;
						
						var dgColumn:AdvancedDataGridColumn = new AdvancedDataGridColumn();
						dgColumn.dataField = (signature[i]).FIELDNAME;
						dgColumn.headerText = (signature[i]).SCRTEXT_L;	
						
						//Getting column width based on the content
						dgColumn.width = getMaxColumWidth2(dgColumn.dataField, getMaxHeaderWidth(signature, i), outputXMLReportData);
						dgColumn.minWidth = dgColumn.width/4;
						dgColumn.headerWordWrap = true;
						
						//Checking if column sorting is enabled
						//dgColumn.sortable = getSortable(_CommonModel.currentState.queryName);
						
						//Adding sorting functionality based on data type
						if(dgColumn.sortable)
						{
							if(signature[i]['DATATYPE'] == 'NUMC' && (signature[i]['FIELDNAME'] as String).indexOf('CALMO') != -1)
								dgColumn.sortCompareFunction = fieldCallMonthSorter((signature[i]).FIELDNAME);
								
							else if(signature[i]['DATATYPE'] == 'NUMC' ||
								signature[i]['DATATYPE'] == 'QUAN' || 
								signature[i]['DATATYPE'] == 'INT4' || 
								signature[i]['DATATYPE'] == 'CURR')
								dgColumn.sortCompareFunction = fieldNumericSorter((signature[i]).FIELDNAME);
								
							else if(signature[i]['DATATYPE'] == 'DATS')
								dgColumn.sortCompareFunction = fieldDateSorter((signature[i]).FIELDNAME);
							else if(signature[i]['DATATYPE'] == 'CHAR' && (signature[i]['FIELDNAME'] as String).indexOf('VALUE') != -1)
								dgColumn.sortCompareFunction = fieldNumericSorter((signature[i]).FIELDNAME);
						}
						
						
						//Adding Cell renderers
					/*	addDatagridRenderers(_CommonModel.currentState.queryName, (signature[i]).FIELDNAME,
							dgColumn);*/
						
						
						myColumns.push(dgColumn);
						
						/*var enhancedTextFilter:EnhancedTextFilterRenderer = new EnhancedTextFilterRenderer();
						enhancedTextFilter.textInput = new TextInput();
						enhancedTextFilter.textInput.id = signature[i].FIELDNAME;
						enhancedTextFilter.textInput.name = signature[i].FIELDNAME;
						enhancedTextFilter.textInput.addEventListener(Event.CHANGE, searchData);
						enhancedTextFilter.id = signature[i].FIELDNAME;
						enhancedTextFilter.name = signature[i].FIELDNAME;
						enhancedTextFilter.width = (myColumns[searchFieldBarIndex] as AdvancedDataGridColumn).width;
						enhancedTextFilter.currentView = myView;
						myView.bar1.addChild(enhancedTextFilter);*/
					}
				}
				/*createGroupedColumns(myColumns);
				myView.summaryData.groupedColumns = finalizedGroup;
				myView.summaryData.addEventListener(ScrollEvent.SCROLL, Sync_Datagrid_Slider_With_SearchBar_Slider);
				myView.summaryData.addEventListener(AdvancedDataGridEvent.COLUMN_STRETCH, resize_search_textInputs);
				*/
				
			}
			/*myView.summaryData.dataProvider = 
				_CommonModel.outputXMLReportData;*/
			dataGridColumns = myColumns;
		}
		
		
		private function getMaxHeaderWidth(singnature:ArrayCollection, index:int):int
		{
			var a:Object = singnature[index];
			var currentLength:int = a.SCRTEXT_L.length;
			
			if(a.hasOwnProperty('HEADERS_INFO'))
			{
				for(var i:int=0; i < a.HEADERS_INFO.length; i++)
				{
					if(a.HEADERS_INFO[i].SCRTEXT_L.length > currentLength)
						currentLength = a.HEADERS_INFO[i].SCRTEXT_L.length; 
				}
			}
			
			return currentLength;
		}
		
		/**
		 * This function will return the with of the last datagrid column on the right.
		 * @return : column width (Number)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		protected function getMaxColumWidth2(dataField:String, headerLength:int, myData:ArrayCollection):int
		{
			var maxLength:int = 0;
			const STATIC_WIDTH:Number = 6.2;
			for(var a:int = 0; a < myData.length; a++)
			{
				var str:String = myData[a][dataField];
				if(str == null)
					str = "#";
				
				if(str.length > maxLength)
				{
					maxLength = str.length;
				}
			}
			
			if(maxLength == 0)
			{
				maxLength = STATIC_WIDTH * headerLength  * 1.5;
			}
				
			else if(maxLength == headerLength)
			{	
				maxLength = STATIC_WIDTH * headerLength * 1.5;
			}
				
				
			else if( headerLength > maxLength)
			{
				if((headerLength /1.3) > maxLength)
					maxLength = STATIC_WIDTH * headerLength;
				else
					maxLength = STATIC_WIDTH * maxLength * 1.5;
			}
				
			else
			{
				maxLength = STATIC_WIDTH * maxLength * 1.5;
			}
			
			return maxLength;
		}
		
		
		/**
		 * This function is the default function used by the datagrid in 
		 * sorting the columns that has callmonth values
		 * @param : field (string to be sorted in datagrid)
		 * @return : True (matched), Flas (unmatched)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		private function fieldCallMonthSorter(field:String):Function {
			var regEx:RegExp =  /[\/|.|-]/g;
			return function (obj1:Object, obj2:Object):int 
			{
				var var1:Array =  ((obj1[field]).toString()).split(regEx);
				var var2:Array =  ((obj2[field]).toString()).split(regEx);
				var c1:Number;
				var c2:Number;
				
				if(var1.length == 2)
					c1 = var1[0] * 12 + var1[1]*365;
				else
					c1 = 0;
				
				if(var2.length == 2)
					c2 = var2[0] * 12 + var2[1]*365;
				else
					c2 = 0;
				
				var num:Number = c1 - c2;
				return (num > 0) ? 1 : ((num < 0) ? -1 : 0);
			}
		}
		
		/**
		 * This function is the default function used by the datagrid in 
		 * sorting the columns that has NUMC, QUAN or CURR  data type
		 * @param : field (string to be sorted in datagrid)
		 * @return : True (matched), Flas (unmatched)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		private function fieldNumericSorter(field:String):Function {
			return function (obj1:Object, obj2:Object):int 
			{
				var a1:String  = ((obj1[field]).toString()).replace(FlexConstants.CURRENCY_REGULAR_EXPRISSION, "");
				var a2:String  = ((obj2[field]).toString()).replace(FlexConstants.CURRENCY_REGULAR_EXPRISSION, "");
				if(a1 == '' || a1=='#') a1 = 0;
				if(a2 == '' || a2=='#') a2 = 0;
				var num:Number = ((Number)(a1) - (Number)(a2));
				return (num > 0) ? 1 : ((num < 0) ? -1 : 0);
			}
		}
		
		/**
		 * This function is the default function used by the datagrid in 
		 * sorting the columns that has DATS data type
		 * @param : field (string to be sorted in datagrid)
		 * @return : True (matched), Flas (unmatched)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		private function fieldDateSorter(field:String):Function {
			return function (obj1:Object, obj2:Object):int 
			{
				var a1:String = (obj1[field]).toString();
				var a2:String = (obj2[field]).toString();
				
				var d1:Date = (DateField.stringToDate(a1,FlexConstants.DATE_FORMAT));
				var d2:Date = DateField.stringToDate(a2,FlexConstants.DATE_FORMAT);
				
				if(d1 == null)
					d1 = new Date('1899','01','01');
				if(d2 == null)
					d2 = new Date('1899','01','01');
				
				var c1:Number = d1.date + d1.month*30 + d1.fullYear*365 ; 
				var c2:Number = d2.date + d2.month*30 + d2.fullYear*365 ; 
				
				var num:Number = ((Number)(c1) - (Number)(c2));
				return (num > 0) ? 1 : ((num < 0) ? -1 : 0);
			}
		}
	}
}